package seGobangClient.uiSystem3D;

import java.util.Enumeration;
import javax.media.j3d.*;
import javax.vecmath.*;

/**
 *
 * @author plus
 */
public class RobotGroup extends BranchGroup{
    private TransformGroup TGRotT, TGRotR, TGHandT, TGHandR,TGMoveChess;
    RobotPutChessBehavior putFX;
    
    class RobotPutChessBehavior extends Behavior {

        private WakeupOnElapsedTime TimeCondition;
        private RobotGroup RGTarget;
        private Point2i Dest;
        private double angRes,angDest, ang;
        private double posRes,posDest, pos;
        private double height, heightRes;
        private double handAng;
        private boolean showChess;
        private int count = 0;
        private int Action;

        RobotPutChessBehavior(RobotGroup RG) {
            TimeCondition=new WakeupOnElapsedTime(33);
            RGTarget = RG;
        }

        public void initialize() {
            count = 0;
            this.setEnable(false);
            this.wakeupOn(TimeCondition);
        }
        
        public void putChessMission(Point2i dest){
            Dest=dest;
            ang=angRes=Math.atan(1d/3d);
            pos=posRes=-8d/Math.sin(Math.atan(1d/3d));
            angDest=Math.atan((15d-dest.x)/(15d-dest.y));
            posDest=-(15d-dest.x)/Math.sin(angDest);
            count = 0;
            Action=1;
            showChess=true;
            this.setEnable(true);
            System.err.println(dest);
        }
        
        public void winMission(){
            angRes=ang;
            posRes=pos;
            heightRes=height;
            angDest=0.3*Math.PI;
            posDest=-15;
            count = 0;
            Action=2;
            showChess=false;
            this.setEnable(true);
        }

        public void processStimulus(Enumeration criteria) {
            if (Action==1)      //PutChess
                if(count<=80){
                    if(count<=15)
                        height=5d+count/15d;
                    if(count>15 && count <=45){
                        pos=((count-15d)/30d)*(posDest-posRes)+posRes;
                        ang=((count-15d)/30d)*(angDest-angRes)+angRes;
                    }
                    if(count>45 && count <=55){
                        height=6d-(count-45)/10d;
                        if(count==55){
                            showChess=false;
                            SceneManager.MyCurrentController.doEvent("ChooseChessBoard", Dest);
                        }
                    }
                    if(count>55 && count <=60)
                        height=5d+(count-55)/5d;
                    if(count>60 && count <=75){
                        pos=((count-60d)/15d)*(posRes-posDest)+posDest;
                        ang=((count-60d)/15d)*(angRes-angDest)+angDest;
                    }
                    if(count>75 && count <=80){
                        height=6d-(count-75)/5d;
                        if(count==80) showChess=true;
                    }
                    RGTarget.setMode(height, ang, pos, 0, showChess);
                    count++;
                }else{
                    this.setEnable(false);
                }
            if(Action==2)      //Win
                if (count<=120){
                    if (count<=15){
                        height=heightRes+(3d-heightRes)*(count/15d);
                        ang=angRes+(angDest-angRes)*(count/15d);
                        pos=posRes+(posDest-posRes)*(count/15d);
                        handAng=Math.PI*(count/15d);
                        //System.err.println(handAng);
                    }
                    if(count>15 && count<=105){
                        double param=Math.sin(((count-15d)/30d)*4*Math.PI);
                        handAng=Math.PI+0.25*Math.PI*param;
                    }
                    if(count>105 && count <=120){
                        pos=((count-105d)/15d)*(-8d/Math.sin(Math.atan(1d/3d))-posDest)+posDest;
                        ang=((count-105d)/15d)*(Math.atan(1d/3d)-angDest)+angDest;
                        handAng=Math.PI*(1-(count-105d)/15d);
                        height=3d+(count-105d)/15d*2d;
                    }
                    RGTarget.setMode(height, ang, pos, handAng, showChess);
                    count++;
                }else{
                    this.setEnable(false);
                }
            
            
            this.wakeupOn(TimeCondition);
        }
    }
    
    public RobotGroup() {
        this.setCapability(ALLOW_DETACH);
        init();
        this.compile();
    }
    
    public void init(){
        this.addChild(ObjectFactory.createObject("Model/RobBase"));
        this.addChild(ObjectFactory.createChessTG(new Color3f(1f,1f,1f), 7, 0, -9));
        
        TGRotT=new TransformGroup(getTransform3D(15,5,15));
        TGRotR=new TransformGroup(getTransform3DY(Math.atan(1d/3d)));
            TGRotT.addChild(TGRotR);
            TGRotR.addChild(ObjectFactory.createObject("Model/RobRot"));
        this.addChild(TGRotT);
        
        TGHandT=new TransformGroup(getTransform3D(0,0,-8/Math.sin(Math.atan(1d/3d))));
        TGHandR=new TransformGroup(getTransform3DZ(0));
            TGHandT.addChild(TGHandR);
            TGHandR.addChild(ObjectFactory.createObject("Model/RobHand"));
        TGRotR.addChild(TGHandT);
        
        TGMoveChess=new TransformGroup(getTransform3D(0,-5,0));
        TGMoveChess.addChild(ObjectFactory.createChessTG(new Color3f(1f,1f,1f), 0, 0, 0));
        TGHandR.addChild(TGMoveChess);
        
        TGRotT.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
        TGRotR.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
        TGHandT.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
        TGHandR.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
        TGMoveChess.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
        
        putFX=new RobotPutChessBehavior(this);
        putFX.setSchedulingBounds(new BoundingSphere());
        this.addChild(putFX);
    }
    
    void AIPutChess(Point2i pos){
        putFX.putChessMission(pos);
    }
    
    void AIWin(){
        putFX.winMission();
    }
    
    void setMode(double BaseH, double BaseR, double HandV, double HandR, boolean showChess ){
        TGRotT.setTransform(getTransform3D(15d,BaseH,15d));
        TGRotR.setTransform(getTransform3DY(BaseR));
        TGHandT.setTransform(getTransform3D(0d,0d,HandV));
        TGHandR.setTransform(getTransform3DZ(HandR));
        if (showChess)
            TGMoveChess.setTransform(getTransform3D(0,-5,0));
        else
            TGMoveChess.setTransform(getTransform3D(0,-100,0));
        
    }
    
    private Transform3D getTransform3D(double x, double y, double z){
        Transform3D res=new Transform3D();
        res.set(new Vector3d(x,y,z));
        return res;
    }
    
    private Transform3D getTransform3DY(double ry){
        Transform3D res=new Transform3D();
        res.rotY(ry);
        return res;
    }
    
    private Transform3D getTransform3DZ(double rz){
        Transform3D res=new Transform3D();
        res.rotZ(rz);
        return res;
    }
}
